package com.fy.module.qu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fy.common.consts.QuAnswerConstant;
import com.fy.common.consts.QuTypeConstant;
import com.fy.common.dto.PageDto;
import com.fy.common.enums.ApiErrorEnum;
import com.fy.common.exception.ServiceException;
import com.fy.common.vo.ApiRest;
import com.fy.common.vo.PageResult;
import com.fy.module.qu.dto.QuSaveDto;
import com.fy.module.qu.entity.Qu;
import com.fy.module.qu.entity.QuAnswer;
import com.fy.module.qu.entity.QuRepo;
import com.fy.module.qu.mapper.QuAnswerMapper;
import com.fy.module.qu.mapper.QuMapper;
import com.fy.module.qu.mapper.QuRepoMapper;
import com.fy.module.qu.service.IQuAnswerService;
import com.fy.module.qu.service.IQuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fy.module.qu.vo.QuResultVo;
import com.fy.module.repo.entity.Repo;
import com.fy.module.repo.mapper.RepoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 问题题目 服务实现类
 * </p>
 *
 * @author zhu
 * @since 2023-03-21
 */
@Service
@Slf4j
public class QuServiceImpl extends ServiceImpl<QuMapper, Qu> implements IQuService {
    @Autowired
    private QuAnswerMapper quAnswerMapper;
    @Autowired
    private QuRepoMapper quRepoMapper;
    @Autowired
    private RepoMapper repoMapper;
    @Autowired
    private QuMapper quMapper;

    /**
     * @param quSaveDto
     * @return
     */
    @Override
    @Transactional
    public ApiRest add(QuSaveDto quSaveDto) {
        if (quSaveDto.getId() == null) {
            //1.参数校验
            checkData(quSaveDto);
            //2.题目添加
            //2.1 save qu
            Qu qu = new Qu();
            BeanUtil.copyProperties(quSaveDto, qu, true);
            qu.setId(IdWorker.getIdStr());
            qu.setCreateTime(new Date());
            qu.setUpdateTime(new Date());
            this.baseMapper.insert(qu);
            //2.2 save qu_Answer
            List<QuAnswer> answers = quSaveDto.getAnswers();
            for (QuAnswer answer : answers) {
                answer.setId(IdWorker.getIdStr());
                answer.setQuId(qu.getId());
                quAnswerMapper.insert(answer);
            }

            //2.3 save qu_repo
            for (String repoId : quSaveDto.getRepoIds()) {
                QuRepo quRepo = new QuRepo();
                quRepo.setId(IdWorker.getIdStr());
                quRepo.setQuId(qu.getId());
                quRepo.setQuType(qu.getQuType());
                quRepo.setRepoId(repoId);
                quRepoMapper.insert(quRepo);
                //维护题库的题目数
                repoMapper.updateRepoQUCount(repoId);
            }

            log.info("{}在{}添加题目成功", "张三", new Date());
            return ApiRest.success();
        } else {
            //1.参数校验
            checkData(quSaveDto);
            //2.题目添加
            //2.1 update qu
            Qu qu = new Qu();
            BeanUtil.copyProperties(quSaveDto, qu, true);
            qu.setUpdateTime(new Date());
            this.baseMapper.updateById(qu);
            //2.2 update qu_Answer
            List<QuAnswer> answers = quSaveDto.getAnswers();
            for (QuAnswer answer : answers) {
                //answer.setQuId(qu.getId());
                quAnswerMapper.updateById(answer);
            }

            //2.3 save qu_repo
            UpdateWrapper<QuRepo> quRepoUpdateWrapper = new UpdateWrapper<>();
            quRepoUpdateWrapper.eq("qu_id", qu.getId());
            quRepoMapper.delete(quRepoUpdateWrapper);
            for (String repoId : quSaveDto.getRepoIds()) {
                QuRepo quRepo = new QuRepo();
                quRepo.setId(IdWorker.getIdStr());
                quRepo.setQuId(qu.getId());
                quRepo.setQuType(qu.getQuType());
                quRepo.setRepoId(repoId);
                quRepoMapper.insert(quRepo);
                //维护题库的题目数
                repoMapper.updateRepoQUCount(repoId);
            }
            return ApiRest.success();
        }

    }

    @Override
    public PageResult findPage(PageDto<QuSaveDto> pageDto) {
        if (pageDto == null) {
            throw new ServiceException("参数异常");
        }
        if (pageDto.getNow() <= 0) {
            throw new ServiceException("参数异常");
        }
        if (pageDto.getWhere() == null) {
            throw new ServiceException("参数异常");
        }
        //设置分页
        IPage<Qu> page = new Page<>(pageDto.getNow(), pageDto.getSize());
        //条件构造器
        IPage pageInfo = quMapper.findQuByPage(page, pageDto.getWhere());

        PageResult pageResult = new PageResult();
        pageResult.setTotal(pageInfo.getTotal());
        pageResult.setList(pageInfo.getRecords());
        pageResult.setPages(pageInfo.getPages());
        return pageResult;
    }

    @Override
    @Transactional
    public ApiRest deleteQuById(String quId) {
        //删除qu
        boolean b = this.removeById(quId);
        //维护qu_Answer
        UpdateWrapper<QuAnswer> quAnswerUpdateWrapper = new UpdateWrapper<>();
        quAnswerUpdateWrapper.eq("qu_id", quId);
        int i = quAnswerMapper.delete(quAnswerUpdateWrapper);

        //查询出要删除题目对应的题库id
        QueryWrapper<QuRepo> quRepoQueryWrapper = new QueryWrapper<>();
        quRepoQueryWrapper.eq("qu_id", quId);
        List<QuRepo> quRepoList = quRepoMapper.selectList(quRepoQueryWrapper);
        //维护qu_repo
        UpdateWrapper<QuRepo> quRepoUpdateWrapper = new UpdateWrapper<>();
        quRepoUpdateWrapper.eq("qu_id", quId);
        int j = quRepoMapper.delete(quRepoUpdateWrapper);
        //维护维护题库的题目数
        if (quRepoList.size() > 0) {
            for (QuRepo quRepo : quRepoList) {
                int count = repoMapper.updateRepoQUCount(quRepo.getRepoId());
                if (count < 0) {
                    return ApiRest.failure();
                }
            }
        }
        return j > 0 ? ApiRest.success() : ApiRest.failure();
    }

    @Override
    public QuResultVo findOne(String quId) {
        //查询出quid下的qu信息
        Qu qu = quMapper.selectById(quId);
        //查询出quid下quAnswer的信息
        QueryWrapper<QuAnswer> quAnswerQueryWrapper = new QueryWrapper<>();
        quAnswerQueryWrapper.eq("qu_id", quId);
        List<QuAnswer> quAnswerList = quAnswerMapper.selectList(quAnswerQueryWrapper);
        //查询出quid所处的repo信息
        List<String> repoIdList = quRepoMapper.findRepoList(quId);
        QuResultVo quResultVo = new QuResultVo();
        quResultVo.setQu(qu);
        quResultVo.setAnswers(quAnswerList);
        quResultVo.setRepoIds(repoIdList);
        return quResultVo;
    }


    /**
     * 检查题目是否合理
     *
     * @param qu
     */
    private void checkData(QuSaveDto qu) {

        //如果题目内容为空，则返回题目内容不允许为空
        if (StringUtils.isEmpty(qu.getContent())) {
            throw new ServiceException(ApiErrorEnum.QU_CONTENT_IS_NULL);
        }

        //如果题目的答案为空，则返回未绑定题库
        if (CollectionUtils.isEmpty(Arrays.asList(qu.getRepoIds()))) {
            throw new ServiceException(ApiErrorEnum.QU_REPO_ATLEAST_ONE);
        }

        List<QuAnswer> answers = qu.getAnswers();
        //如果题目类型为简答题，并且整整体解析为空 则报 简答题整题解析不能为空
        if (qu.getQuType() == QuTypeConstant.JDT && qu.getAnalysis()==null || StringUtils.isEmpty(qu.getAnalysis())) {
            throw new ServiceException(ApiErrorEnum.QU_HAS_ANSWER);
        }


        int trueCount = 0;
        for (QuAnswer a : answers) {
            if (StringUtils.isEmpty(a.getContent())) {
                throw new ServiceException(ApiErrorEnum.ANS_HAS_CONTENT);
            }
            if (a.getIsRight() == QuAnswerConstant.RIGHT) {
                trueCount += 1;
            }
        }
        // 如果题目不为简单题，并且正确答案为空，则报 选答题答案选项必须有正确答案
        if (trueCount == 0 && !qu.getQuType().equals(QuTypeConstant.JDT)) {
            throw new ServiceException(ApiErrorEnum.QU_HAS_RIGHT_ANSWER);
        }

        //单选题
        if (qu.getQuType() == QuTypeConstant.RADIO && trueCount > 1) {
            throw new ServiceException(ApiErrorEnum.QU_RADIO_HAS_MULTI_RIGHT_ANSWER);
        }
        //判断题
        if (qu.getQuType() == QuTypeConstant.JUDGE && trueCount > 1) {
            throw new ServiceException(ApiErrorEnum.QU_RADIO_HAS_MULTI_RIGHT_ANSWER);
        }

        //多选题
        if (qu.getQuType() == QuTypeConstant.MULTI && trueCount <= 1) {
            throw new ServiceException(ApiErrorEnum.QU_MULTI_MUST_HAS_MULTI_TRUE_ANSWER);
        }

    }
}
